/**

This file is part of MaCI/GIMnet.

MaCI/GIMnet is free software: you can redistribute it and/or modify it 
under the terms of the GNU Lesser General Public License as published 
by the Free Software Foundation, either version 3 of the License, or 
(at your option) any later version.

MaCI/GIMnet is distributed in the hope that it will be useful, but WITHOUT 
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public 
License for more details.

You should have received a copy of the GNU Lesser General Public 
License along with GIMnet. (See COPYING.LESSER) If not, see 
<http://www.gnu.org/licenses/>.

**/

#include <math.h>
#include "drawutils.h"

#include "owndebug.h"

#define glVertex glVertex3f
#define glNormal glNormal3f

/** Draws a textured box
 *
 * not yet implemented
 */
void drawBoxTextured(float w, float h, float l, GLuint aTextureID)
{
  glEnable (GL_TEXTURE_2D);
  glBindTexture (GL_TEXTURE_2D, aTextureID); ///< We bind the texture already loaded


  glBegin(GL_QUADS);

  glNormal(0,0,-1);
  glTexCoord2f (0.0, 1.0);
  glVertex(-w/2,h/2,-l/2);
  glTexCoord2f (1.0, 1.0);
  glVertex(w/2,h/2,-l/2);
  glTexCoord2f (1.0, 0.0);
  glVertex(w/2,-h/2,-l/2);
  glTexCoord2f (0.0, 1.0);
  glVertex(-w/2,-h/2,-l/2);
      

  glNormal(0,0,1);
  glTexCoord2f (0.0, 1.0);
  glVertex(w/2,h/2,l/2);
  glTexCoord2f (1.0, 1.0);
  glVertex(-w/2,h/2,l/2);
  glTexCoord2f (1.0, 0.0);
  glVertex(-w/2,-h/2,l/2);
  glTexCoord2f (0.0, 0.0);
  glVertex(w/2,-h/2,l/2);
  

  // UP
  glNormal(0,1,0);
  glVertex(-w/2,h/2,l/2);
  glVertex(w/2,h/2,l/2);
  glVertex(w/2,h/2,-l/2);
  glVertex(-w/2,h/2,-l/2);
      

  // DOWN
  glNormal(0,-1,0);
  glVertex(w/2,-h/2,l/2);
  glVertex(-w/2,-h/2,l/2);
  glVertex(-w/2,-h/2,-l/2);
  glVertex(w/2,-h/2,-l/2);
  
  glNormal(-1,0,0);
  glTexCoord2f (0.0, 1.0);
  glVertex(-w/2,h/2,-l/2);
  glTexCoord2f (1.0, 1.0);
  glVertex(-w/2,-h/2,-l/2);
  glTexCoord2f (1.0, 0.0);
  glVertex(-w/2,-h/2,l/2);
  glTexCoord2f (0.0, 0.0);
  glVertex(-w/2,h/2,l/2);
  
  glNormal(1,0,0);
  glTexCoord2f (0.0, 1.0);
  glVertex(w/2,h/2,-l/2);
  glTexCoord2f (1.0, 1.0);
  glVertex(w/2,h/2,l/2);
  glTexCoord2f (1.0, 0.0);
  glVertex(w/2,-h/2,l/2);
  glTexCoord2f (0.0, 0.0);
  glVertex(w/2,-h/2,-l/2);
      
  glEnd();

  glDisable (GL_TEXTURE_2D); ///< We disable the loaded texture

}


void drawBox(float w, float h, float l)
{
  //glPushMatrix();
  //glPushAttrib(GL_ALL_ATTRIB_BITS);
    
  glBegin(GL_QUADS);
  glNormal(0,0,-1);
  glVertex(-w/2,h/2,-l/2);
  glVertex(w/2,h/2,-l/2);
  glVertex(w/2,-h/2,-l/2);
  glVertex(-w/2,-h/2,-l/2);
      
  glNormal(0,0,1);
  glVertex(w/2,h/2,l/2);
  glVertex(-w/2,h/2,l/2);
  glVertex(-w/2,-h/2,l/2);
  glVertex(w/2,-h/2,l/2);
      
  glNormal(0,1,0);
  glVertex(-w/2,h/2,l/2);
  glVertex(w/2,h/2,l/2);
  glVertex(w/2,h/2,-l/2);
  glVertex(-w/2,h/2,-l/2);
      
  glNormal(0,-1,0);
  glVertex(w/2,-h/2,l/2);
  glVertex(-w/2,-h/2,l/2);
  glVertex(-w/2,-h/2,-l/2);
  glVertex(w/2,-h/2,-l/2);
      
  glNormal(-1,0,0);
  glVertex(-w/2,h/2,-l/2);
  glVertex(-w/2,-h/2,-l/2);
  glVertex(-w/2,-h/2,l/2);
  glVertex(-w/2,h/2,l/2);
      
  glNormal(1,0,0);
  glVertex(w/2,h/2,-l/2);
  glVertex(w/2,h/2,l/2);
  glVertex(w/2,-h/2,l/2);
  glVertex(w/2,-h/2,-l/2);
      
  glEnd();
    
  //glPopAttrib();
  //glPopMatrix();
}

void drawBox(float w, float h, float l, float x, float y, float z)
{
  glPushMatrix();
  glTranslatef(x,y,z);
  drawBox(w,h,l);
  glPopMatrix();
}

void drawSphere(float r, int d)
{
  float step = 2*M_PI / d;
  
  float r_up,r_down;
  float z_up,z_down;
  
  //glPushMatrix();
  //glPushAttrib(GL_ALL_ATTRIB_BITS);
    
  glBegin(GL_TRIANGLE_STRIP);
  for (int i=1;i<=d;i++)
    {
      r_up=sin((i-1)*step)*r;
      r_down=sin(i*step)*r;
      z_up=cos((i-1)*step)*r;
      z_down=cos(i*step)*r;
        
      for (int j=0;j<=d;j++)
        {
          glNormal(r_up*cos(j*step)/r, r_up*sin(j*step)/r,z_up/r);
          glVertex(r_up*cos(j*step), r_up*sin(j*step),z_up);
          glNormal(r_down*cos(j*step)/r, r_down*sin(j*step)/r,z_down/r);
          glVertex(r_down*cos(j*step), r_down*sin(j*step),z_down);
        }
        
    }
  glEnd();
    
  //glPopAttrib();
  //glPopMatrix();
}

void drawSphere(float r, int d, float x, float y, float z)
{
  glPushMatrix();
  glTranslatef(x,y,z);
  drawSphere(r,d);
  glPopMatrix();
}

void drawCylinder(float r, float h, int d)
{
  float step = 2*M_PI / d;
  
  //glPushMatrix();
  //glPushAttrib(GL_ALL_ATTRIB_BITS);
    
  //draw end caps
  glBegin(GL_TRIANGLE_FAN);
  glNormal(0,0,1);
  glVertex(0,0,h/2);
  for (int i=0;i<=d;i++)
    {        
      glVertex(r*cos(i*step),r*sin(i*step),h/2);
    }
  glEnd();
  glBegin(GL_TRIANGLE_FAN);
  glNormal(0,0,-1);
  glVertex(0,0,-h/2);
  for (int i=0;i<=d;i++)
    {        
      glVertex(r*cos(-i*step),r*sin(-i*step),-h/2);
    }
  glEnd();
    
  //draw pipe
  glBegin(GL_TRIANGLE_STRIP);
  for (int i=0;i<=d;i++)
    {        
      glNormal(cos(i*step),sin(i*step),0);
      glVertex(r*cos(i*step),r*sin(i*step),h/2);
      glVertex(r*cos(i*step),r*sin(i*step),-h/2);
    }
  glEnd();
    
  //glPopAttrib();
  //glPopMatrix();
}

void drawCylinder(float r, float h, int d, float x, float y, float z)
{
  glPushMatrix();
  glTranslatef(x,y,z);
  drawCylinder(r,h,d);
  glPopMatrix();
}

/*
  void drawCapsule(float w, float h, int d);
  {
  glPushMatrix();
  glPushAttrib(GL_ALL_ATTRIB_BITS);
    
  glBegin();
      
  glEnd();
    
  glPopAttrib();
  glPopMatrix();
  }*/

void drawPlane(float w, float h)
{
  //glPushMatrix();
  //glPushAttrib(GL_ALL_ATTRIB_BITS);
    
  glBegin(GL_QUADS);
  glNormal(0,1,0);
  glVertex(-w/2,0,h/2);
  glVertex(-w/2,0,-h/2);
  glVertex(w/2,0,-h/2);
  glVertex(w/2,0,h/2);
  glEnd();
    
  //glPopAttrib();
  //glPopMatrix();
}
